package com.bluesky.framework.web.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.bluesky.common.Constants;
import com.bluesky.common.bo.LoginUser;
import com.bluesky.common.redis.RedisUtils;
import com.bluesky.common.util.AddressUtils;
import com.bluesky.common.util.IpUtils;
import com.bluesky.framework.web.service.ITokenService;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * Token接口实现
 *
 * @author Kevin
 */
@Service
public class TokenServiceImpl implements ITokenService {

    @Resource
    RedisUtils redisUtils;

    @Override
    public String createToken(LoginUser user) {
        String token = IdUtil.simpleUUID();
        user.setToken(token);
        user.setLoginTime(new Date());
        setUserAgent(user);
        String tokenKey = getTokenKey(token);
        redisUtils.set(tokenKey, user, Constants.USER_TOKEN_EXPIRE);
        return token;
    }

    /**
     * 设置用户代理信息
     *
     * @param loginUser
     */
    public void setUserAgent(LoginUser loginUser) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
        String ipAddress = IpUtils.getClientIP(request);
        loginUser.setIpAddress(ipAddress);
        loginUser.setLoginLocation(AddressUtils.getRealAddressByIp(ipAddress));
        loginUser.setBrowser(userAgent.getBrowser().getName());
        loginUser.setOs(userAgent.getOs().getName());
    }

    @Override
    public boolean checkToken(String token) {
        if (StrUtil.isBlank(token)) {
            return false;
        }
        String tokenKey = getTokenKey(token);
        if (redisUtils.hasKey(tokenKey)) {
            // 有操作 更新token过期时间
            redisUtils.expire(tokenKey, Constants.USER_TOKEN_EXPIRE);
            return true;
        }
        return false;
    }

    @Override
    public void deleteToken(String token) {
        String tokenKey = getTokenKey(token);
        redisUtils.del(tokenKey);
    }

    @Override
    public LoginUser getUserByToken(String token) {
        if (StrUtil.isBlank(token)) {
            return null;
        }
        String tokenKey = getTokenKey(token);
        Object obj = redisUtils.get(tokenKey);
        if (obj == null) {
            return null;
        }
        // 有操作 更新token过期时间
        redisUtils.expire(tokenKey, Constants.USER_TOKEN_EXPIRE);
        return (LoginUser) obj;
    }

    private String getTokenKey(String token) {
        return String.format(Constants.USER_TOKEN_TPL, token);
    }

}
